package com.recSystem.Controller;

import com.fasterxml.jackson.databind.PropertyNamingStrategy;
import com.fasterxml.jackson.databind.annotation.JsonNaming;
import com.recSystem.Entity.DTO.*;
import com.recSystem.Entity.DTO.Param.*;
import com.recSystem.Entity.POJO.HttpResponse;
import com.recSystem.Service.PaperService;
import com.recSystem.Service.RecommendService;
import com.recSystem.Utils.TokenParser;
import io.swagger.v3.oas.annotations.Operation;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("api/paper")
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public class PaperController {

    private final PaperService paperService;
    private final RecommendService recommendService;

    public PaperController(PaperService paperService, RecommendService recommendService) {
        this.paperService = paperService;
        this.recommendService = recommendService;
    }

    @PostMapping("/advancedSearch")
    @Operation(summary = "高级检索论文")
    public HttpResponse<NewPaperSearchDTO> advancedSearchPaper(@RequestBody PaperAdvancedSearchParam param,
                                                               @RequestHeader(value = "Authorization") String token) {
        return paperService.advancedSearchPaper(param, token);
    }

    @PostMapping("/search")
    @Operation(summary = "模糊查询论文")
    public HttpResponse<NewPaperSearchDTO> searchPaper(@RequestBody PaperSearchParam param,
                                                    @RequestHeader(value = "Authorization") String token) {
        return paperService.searchPaper(param, token);
    }
    @PostMapping("/searchTag")
    @Operation(summary = "标签查找")
    public HttpResponse<List> searchTag(@RequestBody PaperSearchParam param,
                                                    @RequestHeader(value = "Authorization") String token) {
        return paperService.searchTag(param, token);
    }

//    @PostMapping("get_citationCount")
//    @Operation(summary = "获取某作者发表论文的被引量")
//    public HttpResponse<List<PaperCiteNetDTO>> getCitationCount(@RequestBody ArxivIdParam param,
//                                                            @RequestHeader(value = "Authorization") String token) {
//        return paperService.getCitations(param, token);
//    }

    @PostMapping("generate_paperKeywords")
    @Operation(summary = "根据论文id获取摘要信息，进而调用py生成关键词云")
    public HttpResponse generatePaperKeywords(@RequestBody PaperIdParam param,
                                                            @RequestHeader(value = "Authorization") String token) {
        return paperService.generatePaperKeywords(param, token);
    }

    @PostMapping("get_citations")
    @Operation(summary = "根据论文在arxiv中对应的id值调用Semantic Scholar API获取引证文献")
    public HttpResponse<List<PaperCiteNetDTO>> getCitations(@RequestBody ArxivIdParam param,
                                                             @RequestHeader(value = "Authorization") String token) {
        return paperService.getCitations(param, token);
    }

    @PostMapping("mock_rec")
    @Operation(summary = "论文可视化模块相关文献推荐返回假数据")
    public HttpResponse<List<PaperCiteNetDTO>> mock_rec(@RequestBody ArxivIdParam param,
                                                             @RequestHeader(value = "Authorization") String token) {
        return paperService.mock_rec(param, token);
    }


    @PostMapping("get_references")
    @Operation(summary = "根据论文在arxiv中对应的id值调用Semantic Scholar API获取参考文献")
    public HttpResponse<List<PaperCiteNetDTO>> getReferences(@RequestBody ArxivIdParam param,
                                                             @RequestHeader(value = "Authorization") String token) {
        return paperService.getReferences(param, token);
    }

    @PostMapping("author_publish")
    @Operation(summary = "根据作者id获取发表论文列表")
    public HttpResponse<AuthorInfoDTO> getPapersByAuthorId(@RequestBody AuthorInfoParam param,
                                                    @RequestHeader(value = "Authorization") String token) {
        return paperService.getPapersByAuthorId(param, token);
    }

//    @PostMapping("author")
//    @Operation(summary = "获取作者信息")
//    public HttpResponse<AuthorInfoDTO> searchAuthor(@RequestBody AuthorInfoParam param,
//                                                    @RequestHeader(value = "Authorization") String token) {
//        return paperService.getAuthorInfo(param, token);
//    }

    @PostMapping("/browsing")
    @Operation(summary = "记录论文浏览历史")
    public HttpResponse addBrowsing(@RequestBody PaperIdParam param, @RequestHeader(value = "Authorization") String token) {
        return paperService.addBrowsing(param,token);
    }

    @PostMapping("/delete_browsing")
    @Operation(summary = "删除论文浏览历史")
    public HttpResponse deleteBrowsing(@RequestBody PaperIdParam param, @RequestHeader(value = "Authorization") String token) {
        return paperService.deleteBrowsing(param,token);
    }

    @PostMapping("favorite")
    @Operation(summary = "修改论文收藏状态")
    // TODO 只有一个属性的情况能不能直接用int映射呢，感觉考虑到后期的扩展的话，感觉最好都用实体类，这样以后往里面添属性更方便
    public HttpResponse modifyFavorite(@RequestBody PaperIdParam param,
                                       @RequestHeader(value = "Authorization") String token) {
        return paperService.modifyFavorite(param, token);
    }

    @PostMapping("paper_detail")
    @Operation(summary = "获取论文详情")
    public HttpResponse<DataPaperDTO> getPaperDetail(@RequestBody PaperIdParam param,
                                                     @RequestHeader(value = "Authorization") String token) {
        return paperService.getPaperDetail(param,token);
    }
    @PostMapping("version")
    @Operation(summary = "获取论文详情")
    public HttpResponse<List> getVersion(@RequestBody PaperIdParam param,
                                                     @RequestHeader(value = "Authorization") String token) {
        return paperService.getVersions(param,token);
    }
    @PostMapping("author_rec")
    @Operation(summary = "根据作者推荐")
    public HttpResponse<RecommendFavoriteDTO> recommendByAuthor(@RequestBody RecommendParam param,
                                                          @RequestHeader(value = "Authorization") String token){
        int userId= TokenParser.parse(token);
        RecommendFavoriteDTO recommendPapers = recommendService.getRecommendByAuthor(param.getMaxLength(), param.getOffset(),
                param.getAuthorId(), userId);
        return new HttpResponse<>(new StatusDTO(0,"获取推荐成功"),recommendPapers);
    }

    @PostMapping("similar")
    @Operation(summary = "根据论文推荐相似论文")
    public HttpResponse<RecommendSimilarDTO> recommendSimilar(@RequestBody RecommendParam param,
                                                   @RequestHeader(value = "Authorization") String token){
        int userId=TokenParser.parse(token);
        RecommendSimilarDTO recommendPaper = recommendService.getSimilarPapers(param.getPaperId(), userId);
        return new HttpResponse<>(new StatusDTO(0,"获取推荐成功"),recommendPaper);
    }

    @PostMapping("/favorite_rec")
    @Operation(summary = "根据收藏推荐论文")
    public HttpResponse<RecommendFavoriteDTO> recommendByFavorite(@RequestBody RecommendParam param,
                                                                  @RequestHeader(value = "Authorization")String token){
        int userId= TokenParser.parse(token);
        RecommendFavoriteDTO recommendPapers = recommendService.getRecommendByFavorite(param.getMaxLength(), param.getOffset(), userId);
        return new HttpResponse<>(new StatusDTO(0,"获取推荐成功"),recommendPapers);

    }
    @PostMapping("/info")
    @Operation(summary = "获取标签信息")
    public HttpResponse<List> getUser(@RequestHeader(value = "Authorization") String token) {
        int userId= TokenParser.parse(token);
        return paperService.gettagInfo(token);
    }
}
